<?php
if (!class_exists('AlfaDecorator')) {


	/**
	 * Site decorator
	 * @author Alecsandru Gabriel DINU
	 * @since Jun 12, 2008 
	 */
	class AlfaDecorator {

		const configFile = "decorators.xml";
		const configFile_cache = "decorator_cache.php";
		private $cacheFilename;
		private $patterns = array();
		private $devMode = array();
		private $getters = array();
		private $context = null;
		private $translator = null;

		public function __construct($devMode = false) {
			$config = AlfaConfiguration::getInstance();
			$this->cacheFilename = $config->getString('cache/dir') . "/" . self::configFile_cache;
			$this->devMode = $devMode;
			$this->load();
		}

		private function load() {
			if ($this->devMode) { // load the configuration every time
				$this->patterns = $this->loadConfiguration();
				$this->writeConfigToFile($this->patterns);
			} else { //try to load the configuration from cache
				// Is our cache available? Recreate it!
				if(!is_readable($this->cacheFilename)) {
					$this->writeConfigToFile($this->loadConfiguration());
				}
				require_once $this->cacheFilename;
				$this->patterns =& $GLOBALS['decoratorConfigurationData'];
			}
		}

		/**
		 * Load config from xml and store it into
		 * an array
		 *
		 * @return unknown
		 */
		private function loadConfiguration() {
			$xmlStr = FileUtilities::getFileContent(self::configFile);
			$xml = new SimpleXMLElement($xmlStr);

			// Generates a the list with all the actions
			// from all the packages
			$patterns = array();
			foreach ($xml->decorator as $decorator) {
				foreach ($decorator->pattern as $pattern) {
					$patterns[(string)$pattern] = $decorator["page"];
				}
			}

			return $patterns;
		}

		private function writeConfigToFile($config) {
			/* Generate php cache file */
			$cache_content = "<?php\n// this is a automatically generated cache file.\n\n";
			foreach($config as $pattern => $page) {
				$cache_content .= "\$GLOBALS['decoratorConfigurationData']['$pattern'] = '$page';\n";
			}
			$cache_content .= "?>";
			if($cacheFilename_handle = fopen($this->cacheFilename, "w+")) {
				fwrite($cacheFilename_handle, $cache_content);
				/* Allow ftp users to access/modify/delete cache file, suppress chmod errors here */
				@chmod($this->cacheFilename, 0664);
			}
		}
		
		public function setTranslator($translator) {
			$this->translator = $translator;
		}
		
		public function setContext($context) {
			$this->context = $context;
		}
		
		public function setGetters($getters) {
			$this->getters = $getters;
		}

		public function decorate($page) {
			try {
				$templateManager =
					new AlfaSmartyTemplateEngine($this->getDecorator($page), $page);

				foreach($this->getters as $k => $v) {

					if (is_object($v)) {
						$templateManager->addObject($k , $v);	
					} else {
						$templateManager->mergeField($k, $v);	
					}
				}
				
				// merge context info
				$templateManager->mergeField("site_url", $this->context->getContextPath());
				
				global $core_root;	
				$templateManager->mergeField("core_root", $core_root);
				
				// also add Context and Translator objects to template 
				// environment if available
				if ($this->translator != null) {
					$templateManager->mergeFunction("trn", array(&$this->translator, "translate"));
				}	
				if ($this->context != null) {
					$templateManager->mergeFunction("url", array(&$this->context, "composeURL"));
				}	
				
			} catch (UndefinedKeyException $e) {
				$templateManager = new AlfaSmartyTemplateEngine($page, "");
			}
			$templateManager->show();
		}

		private function getDecorator($key) {
			foreach ($this->patterns as $pattern => $page) {
				$p = $pattern;
				$p = str_replace('.', '\.', $p);
				$p = str_replace('*', '.', $p);

				if (eregi($p, $key)) {
					return $page;
				}
			}
				
			throw new UndefinedKeyException(" Not decorator found for '$key'");
		}

	}
}